trigger Cald_CalculateAttainmentForClaims on Callidus_Claim__c (after update) 
{
    Map<Id, Id> participantsMap = new Map<Id, Id>();
    Map<Id, Id> plansMap = new Map<Id, Id>();
    List<Callidus_Plan_Participant__c> ppList = new List<Callidus_Plan_Participant__c>();
    List<Callidus_Plan_Participant__c> updatePpList = new List<Callidus_Plan_Participant__c>();
    List<Callidus_Claim__c> claimCommissionsChangedList = new List<Callidus_Claim__c>();
    Map<Integer, String> getMonth = new Map<Integer, String>();
    getMonth.put(1, 'Jan');
    getMonth.put(2, 'Feb');
    getMonth.put(3, 'Mar');
    getMonth.put(4, 'Apr');
    getMonth.put(5, 'May');
    getMonth.put(6, 'Jun');
    getMonth.put(7, 'Jul');
    getMonth.put(8, 'Aug');
    getMonth.put(9, 'Sep');
    getMonth.put(10, 'Oct');
    getMonth.put(11, 'Nov');
    getMonth.put(12, 'Dec');
    
    Map<String, String> getAdjacentPeriod = new Map<String, String>();
    List<String> periodList = new List<String>();
    
    Callidus_Plan_Participant__c pp = null;
    Integer yearNo = 0;
    String currentPeriod = '';
    Callidus_Plan_Participant__c[] planParticipantsList = new Callidus_Plan_Participant__c[]{};
    
    try
    {
        Callidus_Claim__c[] updatedClaimsList = [select id, Attainment__c, Credit__c, Adjusted_Credit__c, Adjusted_Commission__c, Commission_Amount__c, Commission_Rate__c, Participant__c, Plan__c, Claim_Status__c, Temporary_Status__c, Opportunity__r.CloseDate from Callidus_Claim__c where id in :Trigger.new and Claim_Status__c = 'Approved'];
        Callidus_Claim_Status_Credit__c[] existingCSCList = null;
        for(Callidus_Claim__c c : updatedClaimsList)
        {
            if(c.Claim_Status__c == 'Approved' && c.Temporary_Status__c == null)
            {
                yearNo = c.Opportunity__r.CloseDate.year();//get the year of the Opportunity
                currentPeriod = getMonth.get(c.Opportunity__r.CloseDate.month())+'-'+yearNo;
                participantsMap.put(c.Participant__c, c.Participant__c);
                if(c.Plan__c != null)
                    plansMap.put(c.Plan__c, c.Plan__c);
            }
            
			existingCSCList = [select id, Participant__c, Amount__c, Commission__c, FYear__c, Claim_Status__c from Callidus_Claim_Status_Credit__c where Participant__c in :participantsMap.keySet() and FYear__c = :yearNo];            
			for(Callidus_Claim_Status_Credit__c csc :existingCSCList)
			{
				if(csc.Claim_Status__c == 'Pending Claims')
				{
					csc.Amount__c -= c.Adjusted_Credit__c;
					csc.Commission__c -= c.Adjusted_Commission__c;
				}
				else if(csc.Claim_Status__c == 'Approved Claims')
				{
					csc.Amount__c += c.Adjusted_Credit__c;
					csc.Commission__c += c.Adjusted_Commission__c;
				}
			}	 
        }
        
        getAdjacentPeriod.put('Jan-'+yearNo, '');
        getAdjacentPeriod.put('Feb-'+yearNo, 'Jan-'+yearNo);
        getAdjacentPeriod.put('Mar-'+yearNo, 'Feb-'+yearNo);
        getAdjacentPeriod.put('Apr-'+yearNo, '');
        getAdjacentPeriod.put('May-'+yearNo, 'Apr-'+yearNo);
        getAdjacentPeriod.put('Jun-'+yearNo, 'May-'+yearNo);
        getAdjacentPeriod.put('Jul-'+yearNo, '');
        getAdjacentPeriod.put('Aug-'+yearNo, 'Jul-'+yearNo);
        getAdjacentPeriod.put('Sep-'+yearNo, 'Aug-'+yearNo);
        getAdjacentPeriod.put('Oct-'+yearNo, '');
        getAdjacentPeriod.put('Nov-'+yearNo, 'Oct-'+yearNo);
        getAdjacentPeriod.put('Dec-'+yearNo, 'Nov-'+yearNo);

        periodList.add('Jan-'+yearNo);
        periodList.add('Feb-'+yearNo);
        periodList.add('Mar-'+yearNo);
        periodList.add('Apr-'+yearNo);
        periodList.add('May-'+yearNo);
        periodList.add('Jun-'+yearNo);
        periodList.add('Jul-'+yearNo);
        periodList.add('Aug-'+yearNo);
        periodList.add('Sep-'+yearNo);
        periodList.add('Oct-'+yearNo);
        periodList.add('Nov-'+yearNo);
        periodList.add('Dec-'+yearNo);

        if(plansMap.size() > 0)
        {
            planParticipantsList = [select id, Period__c, PTD_Attainment__c, QTD_Attainment__c, YTD_Attainment__c, PTD_Commission__c, QTD_Commission__c, YTD_Commission__c, PTD_Credit__c, QTD_Credit__c, YTD_Credit__c  from Callidus_Plan_Participant__c where Plan__c in :plansMap.keyset() and Participant__c in :participantsMap.keyset() and FYear__c = :yearNo order by createddate];
            
            Callidus_Plan__c[] plansList = [select id, Quota__c, OTE__c, (SELECT Participant__c, Quota__c FROM Plan_Assignable__r) from Callidus_Plan__c where id in :plansMap.keyset()];
            Double Quota = 0;
            for(Integer j=0; j<plansList[0].Plan_Assignable__r.size(); j++)
            {
                if(plansList[0].Plan_Assignable__r[j].Participant__c == participantsMap.values().get(0))
                    Quota = plansList[0].Plan_Assignable__r[j].Quota__c;
            }
            Double OTE = plansList[0].OTE__c;
        
        
			for(Callidus_Claim_Status_Credit__c csc :existingCSCList)
			{
				if(csc.Claim_Status__c == 'Pending Claims')
	        		csc.Attainment__c = (csc.Amount__c.doubleValue() * 100) / Quota;
				else if(csc.Claim_Status__c == 'Approved Claims')
	        		csc.Attainment__c = (csc.Amount__c.doubleValue() * 100) / Quota;
			}	 
			update existingCSCList;
			
            Callidus_Rate__c[] ratesList = [select Min_Attainment__c, Max_Attainment__c, Min_Credit__c, Max_Credit__c, Rate_Type__c, Rate__c from Callidus_Rate__c where Plan__c = :plansList[0].id];
            String rateType = ratesList[0].Rate_Type__c;
            
            List<Callidus_Claim__c> creditClaimsList = [select Adjusted_Credit__c, Adjusted_Commission__c from Callidus_Claim__c where Plan__c in :plansMap.keySet() and Participant__c in :participantsMap.keyset() and Claim_Status__c = 'Approved'];
            Double approvedClaimedCredit = 0;
            Double approvedClaimedCommission = 0;
            
            Boolean obtainOTE = false;
            for(Callidus_Claim__c c: creditClaimsList)
            {
                approvedClaimedCredit += c.Adjusted_Credit__c;
                approvedClaimedCommission += c.Adjusted_Commission__c;
                
            }
            
            List<Double> ratePercentList = new List<Double>();
            if(rateType == 'Attainment')
            {
                Double attPercent = (approvedClaimedCredit  * 100)/ Quota;
    
                for(Callidus_Rate__c r : ratesList)
                {
                    if(attPercent >= r.Min_Attainment__c && attPercent <= r.Max_Attainment__c)
                    {
                        ratePercentList.add(r.Rate__c);
                        break;
                    }
                }   

                for(Callidus_Claim__c c: updatedClaimsList)
                {
                    c.Attainment__c = attPercent;
                    approvedClaimedCommission -= c.Adjusted_Commission__c;
                    c.Adjusted_Commission__c = (c.Adjusted_Credit__c * ratePercentList[0])/100;
                    approvedClaimedCommission += c.Adjusted_Commission__c;
                    c.Commission_Rate__c = ratePercentList[0];
                    c.Temporary_Status__c = 'Approved';
                    claimCommissionsChangedList.add(c);
                
                    if(planParticipantsList.size() == 0)
                    {
                        pp = new Callidus_Plan_Participant__c(Participant__c = c.Participant__c, OwnerId = c.Participant__c, Plan__c = c.Plan__c, YTD_Attainment__c = attPercent, YTD_Credit__c = c.Adjusted_Credit__c, PTD_Credit__c = c.Adjusted_Credit__c, QTD_Credit__c = c.Adjusted_Credit__c, YTD_Commission__c = c.Adjusted_Commission__c,  QTD_Commission__c = c.Adjusted_Commission__c, PTD_Commission__c = c.Adjusted_Commission__c, FYear__c = yearNo, period__c = currentPeriod);
                        ppList.add(pp);
                    }
                    else
                    {
                        Boolean currentPeriodExists = false;
                        Callidus_Plan_Participant__c existPlanParticipant = null;
                        Callidus_Plan_Participant__c adjacentPlanParticipant = null;
                        for(Integer i=0; i<planParticipantsList.size(); i++)
                        {
                            if(planParticipantsList[i].Period__c == currentPeriod)
                            {
                                existPlanParticipant = planParticipantsList[i];
                                //if(i != 0)
                                    //adjacentPlanParticipant = planParticipantsList[i-1];
                                break;
                            }
                        }//end of for(Integer i=0;)

                        if(existPlanParticipant == null)// a new entry with the current period in Plan Participant object
                        {
                            pp = new Callidus_Plan_Participant__c(Participant__c = c.Participant__c, OwnerId = c.Participant__c, Plan__c = c.Plan__c, YTD_Attainment__c = attPercent, YTD_Credit__c = approvedClaimedCredit, PTD_Credit__c = c.Adjusted_Credit__c, QTD_Credit__c = c.Adjusted_Credit__c, YTD_Commission__c = approvedClaimedCommission,  QTD_Commission__c = c.Adjusted_Commission__c, PTD_Commission__c = c.Adjusted_Commission__c, FYear__c = yearNo, period__c = currentPeriod);
                            ppList.add(pp);
                            
                        }                       
                        else
                        {
                            existPlanParticipant.YTD_Attainment__c = attPercent;
                            existPlanParticipant.YTD_Credit__c = approvedClaimedCredit;
                            existPlanParticipant.PTD_Credit__c += c.Adjusted_Credit__c;
                            existPlanParticipant.QTD_Credit__c += c.Adjusted_Credit__c;
                            existPlanParticipant.YTD_Commission__c = approvedClaimedCommission;
                            existPlanParticipant.QTD_Commission__c += c.Adjusted_Commission__c;
                            existPlanParticipant.PTD_Commission__c += c.Adjusted_Commission__c; 
                            
                            updatePpList.add(existPlanParticipant);
                                                
                        }
                    }
                    
                }
            }//end of (rateType == 'Attainment')
            else//if rateType is Credit
            {
                for(Callidus_Rate__c r : ratesList)
                {
                    if(approvedClaimedCredit >= r.Min_Credit__c && approvedClaimedCredit <= r.Max_Credit__c)
                    {
                        ratePercentList.add(r.Rate__c);
                        break;
                    }
                }   
                
                for(Callidus_Claim__c c: updatedClaimsList)
                {
                    c.Attainment__c = approvedClaimedCredit;
                    approvedClaimedCommission -= c.Adjusted_Commission__c;
                    c.Adjusted_Commission__c = (c.Adjusted_Credit__c * ratePercentList[0])/100;
                    approvedClaimedCommission += c.Adjusted_Commission__c;
                    c.Commission_Rate__c = ratePercentList[0];
                    c.Temporary_Status__c = 'Approved';
                    claimCommissionsChangedList.add(c);
                    
                    if(planParticipantsList.size() == 0)
                    {
                        pp = new Callidus_Plan_Participant__c(Participant__c = c.Participant__c, OwnerId = c.Participant__c, Plan__c = c.Plan__c, YTD_Credit__c = c.Adjusted_Credit__c, PTD_Credit__c = c.Adjusted_Credit__c, QTD_Credit__c = c.Adjusted_Credit__c, YTD_Commission__c = c.Adjusted_Commission__c,  QTD_Commission__c = c.Adjusted_Commission__c, PTD_Commission__c = c.Adjusted_Commission__c, FYear__c = yearNo, period__c = currentPeriod);
                        ppList.add(pp);
                    }
                    else
                    {
                        Boolean currentPeriodExists = false;
                        Callidus_Plan_Participant__c existPlanParticipant = null;
                        Callidus_Plan_Participant__c adjacentPlanParticipant = null;
                        for(Integer i=0; i<planParticipantsList.size(); i++)
                        {
                            if(planParticipantsList[i].Period__c == currentPeriod)
                            {
                                existPlanParticipant = planParticipantsList[i];
                                //if(i != 0)
                                    //adjacentPlanParticipant = planParticipantsList[i-1];
                                break;
                            }
                        }//end of for(Integer i=0;)

                        if(existPlanParticipant == null)// a new entry with the current period in Plan Participant object
                        {
/*                          if(getAdjacentPeriod.get(currentPeriod) != '')
                            {
                                String adjacentPeriod = getAdjacentPeriod.get(currentPeriod);
                                for(Integer i=0; i<planParticipantsList.size(); i++)
                                {
                                    if(planParticipantsList[i].Period__c == adjacentPeriod)
                                    {
                                        adjacentPlanParticipant = planParticipantsList[i];
                                        break;
                                    }
                                }
                            }*/
                            
                            //if(planParticipantsList.size() > 0)
                                //adjacentPlanParticipant = planParticipantsList[planParticipantsList.size() - 1];

//                          if(adjacentPlanParticipant == null)
    //                          pp = new Callidus_Plan_Participant__c(Participant__c = c.Participant__c, Plan__c = c.Plan__c, YTD_Attainment__c = attPercent, YTD_Credit__c = c.Adjusted_Credit__c, PTD_Credit__c = c.Adjusted_Credit__c, QTD_Credit__c = c.Adjusted_Credit__c, YTD_Commission__c = c.Adjusted_Commission__c,  QTD_Commission__c = c.Adjusted_Commission__c, PTD_Commission__c = c.Adjusted_Commission__c, FYear__c = yearNo, period__c = currentPeriod);
      //                    else
                            pp = new Callidus_Plan_Participant__c(Participant__c = c.Participant__c, OwnerId = c.Participant__c, Plan__c = c.Plan__c, YTD_Credit__c = approvedClaimedCredit, PTD_Credit__c = c.Adjusted_Credit__c, QTD_Credit__c = c.Adjusted_Credit__c, YTD_Commission__c = approvedClaimedCommission,  QTD_Commission__c = c.Adjusted_Commission__c, PTD_Commission__c = c.Adjusted_Commission__c, FYear__c = yearNo, period__c = currentPeriod);
                            ppList.add(pp);
                            
                        }                       
                        else
                        {
                            existPlanParticipant.YTD_Credit__c = approvedClaimedCredit;
                            existPlanParticipant.PTD_Credit__c += c.Adjusted_Credit__c;
                            existPlanParticipant.QTD_Credit__c += c.Adjusted_Credit__c;
                            existPlanParticipant.YTD_Commission__c = approvedClaimedCommission;
                            existPlanParticipant.QTD_Commission__c += c.Adjusted_Commission__c;
                            existPlanParticipant.PTD_Commission__c += c.Adjusted_Commission__c; 
                            
                            updatePpList.add(existPlanParticipant);
                                                
                        }
                    }
                    
                    
                }
            }//end of else
        }//end of if(plansMap.size() > 0))
        else if(updatedClaimsList[0].Claim_Status__c == 'Approved' && updatedClaimsList[0].Temporary_Status__c == null)//if Claim is Standalone
        {
            planParticipantsList = [select id, Period__c, PTD_Attainment__c, QTD_Attainment__c, YTD_Attainment__c, PTD_Commission__c, QTD_Commission__c, YTD_Commission__c, PTD_Credit__c, QTD_Credit__c, YTD_Credit__c  from Callidus_Plan_Participant__c where Participant__c in :participantsMap.keyset() and FYear__c = :yearNo order by createddate];
            Decimal Max_YTDCredit = 0;
            Decimal Max_YTDCommission = 0;
            
            for(Callidus_Claim__c c: updatedClaimsList)
            {
                
                if(planParticipantsList.size() == 0)
                {
                    pp = new Callidus_Plan_Participant__c(Participant__c = c.Participant__c, OwnerId = c.Participant__c,YTD_Credit__c = c.Adjusted_Credit__c, PTD_Credit__c = c.Adjusted_Credit__c, QTD_Credit__c = c.Adjusted_Credit__c, YTD_Commission__c = c.Adjusted_Commission__c,  QTD_Commission__c = c.Adjusted_Commission__c, PTD_Commission__c = c.Adjusted_Commission__c, FYear__c = yearNo, period__c = currentPeriod);
                    ppList.add(pp);
                }
                else
                {
                    Boolean currentPeriodExists = false;
                    Callidus_Plan_Participant__c existPlanParticipant = null;
                    Callidus_Plan_Participant__c adjacentPlanParticipant = null;
                    for(Integer i=0; i<planParticipantsList.size(); i++)
                    {
                        if(planParticipantsList[i].Period__c == currentPeriod)
                        {
                            existPlanParticipant = planParticipantsList[i];
                            break;
                        }
                    }//end of for(Integer i=0;)

                    for(Integer i=0; i<planParticipantsList.size(); i++)
                    {
                        if(Max_YTDCredit < planParticipantsList[i].YTD_Credit__c)
                            Max_YTDCredit = planParticipantsList[i].YTD_Credit__c;
                        if(Max_YTDCommission < planParticipantsList[i].YTD_Commission__c)
                            Max_YTDCommission = planParticipantsList[i].YTD_Commission__c;
                    }//end of for(Integer i=0;)

                    if(existPlanParticipant == null)// a new entry with the current period in Plan Participant object
                    {
                        pp = new Callidus_Plan_Participant__c(Participant__c = c.Participant__c, OwnerId = c.Participant__c,YTD_Credit__c = (Max_YTDCredit + c.Adjusted_Credit__c), PTD_Credit__c = c.Adjusted_Credit__c, QTD_Credit__c = c.Adjusted_Credit__c, YTD_Commission__c = (Max_YTDCommission + c.Adjusted_Commission__c),  QTD_Commission__c = c.Adjusted_Commission__c, PTD_Commission__c = c.Adjusted_Commission__c, FYear__c = yearNo, period__c = currentPeriod);
                        ppList.add(pp);
                        
                    }                       
                    else
                    {
                        existPlanParticipant.YTD_Credit__c = Max_YTDCredit + c.Adjusted_Credit__c;
                        existPlanParticipant.PTD_Credit__c += c.Adjusted_Credit__c;
                        existPlanParticipant.QTD_Credit__c += c.Adjusted_Credit__c;
                        existPlanParticipant.YTD_Commission__c = Max_YTDCommission + c.Adjusted_Commission__c;
                        existPlanParticipant.QTD_Commission__c += c.Adjusted_Commission__c;
                        existPlanParticipant.PTD_Commission__c += c.Adjusted_Commission__c; 
                        
                        updatePpList.add(existPlanParticipant);
                                            
                    }
                }
                c.Attainment__c = Max_YTDCredit + c.Adjusted_Credit__c;
                c.Temporary_Status__c = 'Approved';
                claimCommissionsChangedList.add(c);
                
            }
        } 
        if(ppList.size() > 0)
            insert ppList;
            
        if(updatePpList.size() > 0)
            update updatePpList;
            
        if(claimCommissionsChangedList.size() > 0)
            update claimCommissionsChangedList;
    }
    catch(Exception e)
    {
    }

}